#include "..\myLibrary.h"
DWORD WINAPI ConnectNewClient(LPVOID param)
{
    SOCKET udp_sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    SocketG UDP(udp_sock);
    char buffer[1024];
    int buffer_size = sizeof(buffer);
    sockaddr_in  udp;
    udp.sin_family=AF_INET;
    udp.sin_port=htons(5555);
    udp.sin_addr.s_addr=htonl(INADDR_ANY);    
    SOCKADDR_IN nsa;
    int sizeof_nsa = sizeof(nsa);
    if(bind(udp_sock, (SOCKADDR *)&udp, sizeof(udp))==SOCKET_ERROR)
        {
        std::cout << "bind error" << std::endl;
        system("pause");
        return -1;
    }   
    while(1)
    {
        recvfrom(udp_sock,buffer, buffer_size,0,(SOCKADDR *)&nsa, &sizeof_nsa);
        std::cout<<buffer;
        char buf[128];
        char ipadr [256];
        hostent *h;  
        if (gethostname(buf, 128) == 0)
        {
            h=gethostbyname(&buf[0]);
            u_long ip = *(u_long *) h->h_addr_list[0];
            char *cip = inet_ntoa(*(in_addr*)&ip);    
            strcpy(ipadr,cip);           
        } 
        sendto(udp_sock,ipadr, strlen(ipadr),0,(SOCKADDR *)&nsa, sizeof(nsa));
    }
    return 0;
}
DWORD WINAPI ConnectClient(LPVOID param)
{
	Packet GetData;
	SOCKET NS;
	NS= *(SOCKET *)param;
	SocketG WorkOnServer(NS);
	std::vector<char> file(sizeof(Packet));       
	while(1)
	{
		int k = recv(NS,&file.front(),sizeof(Packet), 0);
		if(k <= 0)        
		{
			Database.erase(GetData.ReturnAddr);
			break;
		}
		else
		{
			GetData = *(reinterpret_cast<Packet*>(&file.front()));           
			if (GetData.choise=='1')
			{ 
				Database.insert(std::make_pair(GetData.ReturnAddr, &GetData.NameFile[0]));
				for (auto it = Database.begin(); it != Database.end(); ++it)
				{
					std::cout << it->first << " : " << it->second << std::endl;
				}
			}
			else if(GetData.choise=='2')
			{
				std::string client;
				for (auto it = Database.begin(); it != Database.end(); it++)           
				{
					if(it->second==GetData.NameFile)
					{
						client = it->first.c_str();
						break;
					}
				}

				if (client.length() > 0)
				{
					strcpy(&GetData.ReturnAddr[0],client.c_str());
					GetData.choise='5';
					send(NS,(char *)&GetData,sizeof(Packet),0);
				}
				else
				{
					GetData.choise='0';
					send(NS,(char *)&GetData,sizeof(Packet),0);
				}
			}
			else if(GetData.choise=='3')
			{
				std::string Buffer;                
				for (auto it = Database.begin(); it != Database.end(); ++it)
				{
					Buffer+=it->second;
					Buffer+="\n";
				}
				char len = Buffer.size() + 1; 
				send(NS,&len,1,0);
				send(NS,&Buffer[0],Buffer.size(),0);
			}
			else if(GetData.choise=='4')
			{
				Database.erase(GetData.ReturnAddr);
				break;
			}
		}
	}
	return 0;
}
int main()
{   
	WSAData WSData; 
	WSAStartup(0x202,&WSData); 
	WSADataG Wsd(WSData);
    DWORD thID1;
    HANDLE hThreadForNewClient = CreateThread(NULL, NULL, ConnectNewClient,NULL, NULL, &thID1);  
    ThreadG ResearchServ(hThreadForNewClient);
	SOCKET Server = socket(AF_INET,SOCK_STREAM,0); 
	SocketG ForServer(Server);
	sockaddr_in SA;
	SA.sin_family=AF_INET;  
	SA.sin_port=htons(3135);
	SA.sin_addr.S_un.S_addr=INADDR_ANY;    
	bind(Server,(sockaddr*)&SA,sizeof(SA)); 
	listen(Server,SOMAXCONN); 
	SOCKET NewClient;    
	while ((NewClient = accept(Server,0,0))!=INVALID_SOCKET)
	{          
		std::cout<<"Connected...\n";
		DWORD thID;
		HANDLE hThread = CreateThread(NULL, NULL, ConnectClient, &NewClient, NULL, &thID);  
		ThreadG Server(hThread);
	}
    closesocket(NewClient);
}